/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.esakk001;


/**
 * ramesh *
 */
/*import org.netbeans.api.settings.ConvertAsProperties;
 import org.openide.awt.ActionID;
 import org.openide.awt.ActionReference;
 import org.openide.windows.TopComponent;
 import org.openide.util.NbBundle.Messages;
 */
/**
 * ramesh*
 */
import idea.model.qnrlibrary.CommonParameters;
import idea.model.qnrlibrary.GeneralLovTm;
import idea.model.qnrlibrary.Categories;
import java.awt.BorderLayout;
//import java.awt.Component;
//import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.IntrospectionException;
//import java.beans.PropertyChangeListener;
//import java.beans.PropertyChangeSupport;
//import java.beans.PropertyEditor;
//import java.beans.PropertyEditorSupport;
//import java.io.IOException;
//import java.lang.reflect.InvocationTargetException;
//import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.swing.DefaultComboBoxModel;
//import javax.swing.Icon;
import javax.swing.JComboBox;
//import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
//import javax.swing.KeyStroke;

import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.ErrorManager;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.explorer.ExplorerManager;
import org.openide.explorer.ExplorerUtils;
//import org.openide.explorer.propertysheet.ExPropertyEditor;
//import org.openide.explorer.propertysheet.InplaceEditor;
//import org.openide.explorer.propertysheet.PropertyEnv;
//import org.openide.explorer.propertysheet.PropertyModel;
//import org.openide.explorer.view.ListView;
import org.openide.explorer.view.OutlineView;
//import org.openide.explorer.view.TreeTableView;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.BeanNode;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.nodes.PropertySupport;
import org.openide.nodes.Sheet;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.Lookups;
import org.openide.windows.TopComponent;
//import org.openide.explorer.view.BeanTreeView;
//import org.netbeans.spi.actions.AbstractSavable;
//import org.openide.DialogDisplayer;
//import org.openide.NotifyDescriptor;
//import org.openide.NotifyDescriptor.Confirmation;
//import org.openide.NotifyDescriptor.Message;
import org.openide.awt.ActionReferences;
import org.openide.util.lookup.InstanceContent;
import org.netbeans.swing.outline.Outline;


/**
 * Top component which displays something.
 */
@ConvertAsProperties(
        dtd = "-//org.esakk001//Main//EN" ,
        autostore = false )
@TopComponent.Description(
        preferredID = "MainTopComponent" ,
        //iconBase="SET/PATH/TO/ICON/HERE", 
        persistenceType = TopComponent.PERSISTENCE_ALWAYS )
@TopComponent.Registration( position = 5, mode = "editor" , openAtStartup = false )
@ActionID( category = "Window" , id = "org.esakk001.MainTopComponent" )
@ActionReferences(
        {
    @ActionReference(path = "Menu/Window", position = 1033),
    @ActionReference(path = "Menu/File/Open", position = 1900)
})
@TopComponent.OpenActionRegistration(
        displayName = "#CTL_MainAction" ,
        preferredID = "MainTopComponent" )
@Messages( 
{
    "CTL_MainAction=Main" ,
    "CTL_MainTopComponent=Multi CRUD Window" ,
    "HINT_MainTopComponent=This is a Multi CRUD window"
} )
public final class MainTopComponent extends TopComponent implements ExplorerManager.Provider
{

    /**
     * Position of the first element of a list.
     */
    public final static int FIRST_ELEMENT = 0;
    /**
     *
     */
    private transient ExplorerManager exploMan;
    /**
     *
     */
    private final InstanceContent instanceContent;
    private SearchPanel searchPane;
    /**
     *
     */
//    private OutlineView viewPane;
    private JScrollPane viewPane;


    public MainTopComponent()
    {
        //  initComponents();
        setName( Bundle.CTL_MainTopComponent() );
        setToolTipText( Bundle.HINT_MainTopComponent() );


        this.setLayout( new BorderLayout() );
        this.searchPane = new SearchPanel();
        instanceContent = new InstanceContent();



        this.add( this.searchPane , BorderLayout.PAGE_START );
        //
//        this.viewPane = new JScrollPane();
//        this.add( this.viewPane , BorderLayout.CENTER );

        this.exploMan = new ExplorerManager();
        this.associateLookup( ExplorerUtils.createLookup( exploMan , getActionMap() ) );


    }


    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables

    @Override
    public void componentOpened()
    {
        // TODO add custom code on component opening
    }


    @Override
    public void componentClosed()
    {
        // TODO add custom code on component closing
    }


    private void modify()
    {
        if ( getLookup().lookup( MySavable.class ) == null )
        {

            instanceContent.add( new MySavable() );
        }
    }


    void writeProperties( java.util.Properties p )
    {
        // better to version settings since initial version as advocated at
        // http://wiki.apidesign.org/wiki/PropertyFiles
        p.setProperty( "version" , "1.0" );
        // TODO store your settings
    }


    void readProperties( java.util.Properties p )
    {
        String version = p.getProperty( "version" );
        // TODO read your settings according to their version
    }

    /* private void modify() {
     if (getLookup().lookup(MySavable.class) == null) {
     instanceContent.add(new MySavable());
     }
     }
     */

    private void displayCommonParameters()
    {
        EntityManager entityManager = Persistence
                .createEntityManagerFactory( "QnrLibraryPU" ).createEntityManager();
        // CommonParameters
        List<CommonParameters> cpList =
                entityManager
                .createNamedQuery( "CommonParameters.findAll" )
                .getResultList();

        try
        {
            this.remove( this.viewPane );
            this.viewPane = null;
        }
        catch ( Exception e )
        {
            System.err.println( e );
        }

        //ListView
        this.viewPane = new OutlineView("");
        //this.viewPane = new TreeTableView();

        ( (OutlineView) this.viewPane ).setPropertyColumns(
               
                "Name" , "ParameterName" ,
                "Value" , "Value" ,
                "Description" , "Description" );
        Outline o = ((OutlineView)this.viewPane).getOutline();
        o.setRootVisible( false);
        o.getColumnModel().getColumn( 0 ).setMaxWidth( 30 );
        o.getColumnModel().getColumn( 0 ).setResizable( false );
        // hide the root
        //ask ed

        //( (OutlineView) this.viewPane ).getOutline().setRootVisible( false );
// ask ed
        // hide the root


        this.add( this.viewPane , BorderLayout.CENTER );

        if ( cpList.isEmpty() == false )
        {
            this.exploMan.setRootContext( new AbstractNode(
                    Children.create( new CommonParametersFactory( cpList ) , true ) ) );
        }
        // re-validates the window's contents and re-draws them.
        this.revalidate();
    }


    private void displayCategories()
    {
        EntityManager entityManager = Persistence
                .createEntityManagerFactory( "QnrLibraryPU" ).createEntityManager();
        // CommonParameters
        List<Categories> cpList =
                entityManager
                .createNamedQuery( "Categories.findAll" )
                .getResultList();

        try
        {
            this.remove( this.viewPane );
            this.viewPane = null;
        }
        catch ( Exception e )
        {
            System.err.println( e );
        }

        //ListView
        this.viewPane = new OutlineView("");
        //this.viewPane = new TreeTableView();

        ( (OutlineView) this.viewPane ).setPropertyColumns(
                "category" , "Question Category" ,
                "createdBy" , "Created by" );
        
         Outline o = ((OutlineView)this.viewPane).getOutline();
        o.setRootVisible( false);
        o.getColumnModel().getColumn( 0 ).setMaxWidth( 30 );
        o.getColumnModel().getColumn( 0 ).setResizable( false );
        //((OutlineView) this.viewPane).getOutline();

        // hide the root
        //ask ed
        // ( (OutlineView) this.viewPane ).getOutline().setRootVisible( false );
        // ask ed
        // hide the root


        this.add( this.viewPane , BorderLayout.CENTER );

        if ( cpList.isEmpty() == false )
        {
            this.exploMan.setRootContext( new AbstractNode(
                    Children.create( new CategoriesFactory( cpList ) , true ) ) );
        }
        // re-validates the window's contents and re-draws them.
        this.revalidate();
    }


    /**
     *
     */
    private void displayGeneralLOV()
    {
        EntityManager entityManager = Persistence
                .createEntityManagerFactory( "QnrLibraryPU" ).createEntityManager();
        // CommonParameters
        List<GeneralLovTm> cpList =
                entityManager
                .createNamedQuery( "GeneralLovTm.findAll" )
                .getResultList();

        try
        {
            this.remove( this.viewPane );
            this.viewPane = null;
        }
        catch ( Exception e )
        {
            System.err.println( e );
        }
        this.viewPane = new OutlineView("");
        //this.viewPane = new TreeTableView();

        ( (OutlineView) this.viewPane ).setPropertyColumns(
                "lovType" , "LovType" ,
                "description" , "Description" );
        
         Outline o = ((OutlineView)this.viewPane).getOutline();
        o.setRootVisible( false);
        o.getColumnModel().getColumn( 0 ).setMaxWidth( 30 );
        o.getColumnModel().getColumn( 0 ).setResizable( false );
        // this.viewPane = new ListView();

        this.add( this.viewPane , BorderLayout.CENTER );

        if ( cpList.isEmpty() == false )
        {
            this.exploMan.setRootContext( new AbstractNode(
                    Children.create( new GeneralLovFactory( cpList ) , true ) ) );
        }
        // re-validates the window's contents and re-draws them.
        this.revalidate();
    }


    @Override
    public ExplorerManager getExplorerManager()
    {
        return this.exploMan;
    }

    private static int listCtr = 0;


    private class CategoriesFactory extends ChildFactory<Categories>
    {

        private List<Categories> resultList;


        public CategoriesFactory( List<Categories> cpList )
        {
            this.resultList = cpList;
            //    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }


        @Override
        protected boolean createKeys( List<Categories> list )
        {
            for ( Categories cp : this.resultList )
            {
                list.add( cp );
            }
            return true;//To change body of generated methods, choose Tools | Templates.
        }


        protected Node createNodeForKey( Categories cp )
        {
            try
            {
                return new BeanNode( cp );
            }
            catch ( IntrospectionException ex )
            {
                Exceptions.printStackTrace( ex );
                return null;
            }
//            return new GeneralLovNode( glov );
        }

    }
    /*    @Override
     protected Node createNodeForKey(Categories cp) {
     return new CategoriesNode(cp);
     //            try
     //            {
     //                return new BeanNode( cp );
     //            }
     //            catch ( IntrospectionException ex )
     //            {
     //                Exceptions.printStackTrace( ex );
     //                return null;
     //            }
     }
     }
     */


    private class CategoriesNode extends AbstractNode
    {

        public CategoriesNode( Categories cp )
        {
            super( Children.LEAF , Lookups.fixed( new Object[]
            {
                cp
            } ) );

            this.setDisplayName( cp.getCategory() );
        }


        @Override
        protected Sheet createSheet()
        {
            Sheet sheet = Sheet.createDefault();
            Sheet.Set set = Sheet.createPropertiesSet();
            CommonParameters cp = getLookup().lookup( CommonParameters.class );

            try
            {
                PropertySupport.Reflection cpId = new PropertySupport.Reflection( cp , String.class , "getCommonParametersId" , null );
                Property cpName = new PropertySupport.Reflection( cp , String.class , "getParameterName" , "setParameterName" );
                Property cpValue = new PropertySupport.Reflection( cp , String.class , "getParameterValue" , "setParameterValue" );
                Property cpDesc = new PropertySupport.Reflection( cp , String.class , "getParamDescription" , "setParamDescription" );

                cpId.setName( "ID" );
                cpName.setName( "Name" );
                cpValue.setName( "Value" );
                cpDesc.setName( "Description" );

                set.put( cpId );
                set.put( cpName );
                set.put( cpValue );
                set.put( cpDesc );
            }
            catch ( Exception e )
            {
                ErrorManager.getDefault();
            }

            sheet.put( set );
            return sheet;
        }

    }


    /**
     *
     */
    private class CommonParametersFactory extends ChildFactory<CommonParameters>
    {

        private List<CommonParameters> resultList;


        /**
         * @param cpList
         */
        public CommonParametersFactory( List<CommonParameters> cpList )
        {
            this.resultList = cpList;
        }


        @Override
        protected boolean createKeys( List<CommonParameters> list )
        {
            for ( CommonParameters cp : this.resultList )
            {
                list.add( cp );
            }
            return true;
        }


        @Override
        protected Node createNodeForKey( CommonParameters cp )
        {
            return new CommonParametersNode( cp );
//            try
//            {
//                return new BeanNode( cp );
//            }
//            catch ( IntrospectionException ex )
//            {
//                Exceptions.printStackTrace( ex );
//                return null;
//            }
        }

    }


    /*
     * 
     */
    //private class CommonParametersNode extends BeanNode
    private class CommonParametersNode extends AbstractNode
    {

        public CommonParametersNode( CommonParameters cp )
        {
            super( Children.LEAF , Lookups.fixed( new Object[]
            {
                cp
            } ) );
            this.setDisplayName( cp.getParameterName() );
        }
//        public CommonParametersNode( CommonParameters cp ) throws IntrospectionException
//        {
//            super( cp , Children.LEAF , Lookups.singleton( cp ) );
//            setDisplayName( cp.getParameterName() );
//            setShortDescription( cp.getParamDescription() );
//        }


        @Override
        protected Sheet createSheet()
        {
            Sheet sheet = Sheet.createDefault();
            Sheet.Set set = Sheet.createPropertiesSet();
            CommonParameters cp = getLookup().lookup( CommonParameters.class );

            try
            {
                PropertySupport.Reflection cpId = new PropertySupport.Reflection( cp , String.class , "getCommonParametersId" , null );
                Property cpName = new PropertySupport.Reflection( cp , String.class , "getParameterName" , "setParameterName" );
                Property cpValue = new PropertySupport.Reflection( cp , String.class , "getParameterValue" , "setParameterValue" );
                Property cpDesc = new PropertySupport.Reflection( cp , String.class , "getParamDescription" , "setParamDescription" );

                cpId.setName( "ID" );
                cpName.setName( "Name" );
                cpValue.setName( "Value" );
                cpDesc.setName( "Description" );

                set.put( cpId );
                set.put( cpName );
                set.put( cpValue );
                set.put( cpDesc );
            }
            catch ( Exception e )
            {
                ErrorManager.getDefault();
            }

            sheet.put( set );
            return sheet;
        }

    }


    private class GeneralLovFactory extends ChildFactory<GeneralLovTm>
    {

        private List<GeneralLovTm> resultList;


        /**
         *
         * @param list
         */
        public GeneralLovFactory( List<GeneralLovTm> list )
        {
            this.resultList = list;
        }


        @Override
        protected boolean createKeys( List<GeneralLovTm> list )
        {
            for ( GeneralLovTm glov : this.resultList )
            {
                list.add( glov );
            }
            return true;
        }


        @Override
        protected Node createNodeForKey( GeneralLovTm glov )
        {
            try
            {
                return new BeanNode( glov );
            }
            catch ( IntrospectionException ex )
            {
                Exceptions.printStackTrace( ex );
                return null;
            }
//            return new GeneralLovNode( glov );
        }

    }


    private class GeneralLovNode extends AbstractNode
    {
        //

        public GeneralLovNode( GeneralLovTm gLov )
        {
            super( Children.LEAF , Lookups.fixed( new Object[]
            {
                gLov
            } ) );
            this.setDisplayName( gLov.getDescription() );
        }


        /**
         *
         * @return
         */
        @Override
        protected Sheet createSheet()
        {
            //
            Sheet sheet = Sheet.createDefault();
            //
            Sheet.Set set = Sheet.createPropertiesSet();
            //
            GeneralLovTm gLov = getLookup().lookup( GeneralLovTm.class );

            try
            {
                Property nameProp = new PropertySupport.Reflection( gLov , String.class , "getDescription" , "setDescription" );
                Property colsNumProp = new PropertySupport.Reflection( gLov , String.class , "getLovType" , null );
                Property rowHeightProp = new PropertySupport.Reflection( gLov , String.class , "getCreatedBy" , null );
                Property rowWidthProp = new PropertySupport.Reflection( gLov , Date.class , "getDateCreated" , null );

                nameProp.setName( "Desc" );
                colsNumProp.setName( "Type" );
                rowHeightProp.setName( "Created By" );
                rowWidthProp.setName( "Date Created" );

                set.put( nameProp );
                set.put( colsNumProp );
                set.put( rowHeightProp );
                set.put( rowWidthProp );

            }
            catch ( NoSuchMethodException ex )
            {
                ErrorManager.getDefault();
            }
            //
            sheet.put( set );

            return sheet;
        }

    }

    /*  public class MySavable extends AbstractSavable implements Icon {    
     MySavable() {
     register();
     }
     @Override
     protected String findDisplayName() {
     ;
     return null; 
     }
     @Override
     protected void handleSave() throws IOException {
     Confirmation message = new NotifyDescriptor.Confirmation("Do you want to save \""
     + "\"?",
     NotifyDescriptor.OK_CANCEL_OPTION,
     NotifyDescriptor.QUESTION_MESSAGE);
     Object result = DialogDisplayer.getDefault().notify(message);
     if (NotifyDescriptor.YES_OPTION.equals(result)) {
     // add jpa code for persisting our change
     EntityManager entityManager = Persistence.createEntityManagerFactory("QNRLibraryPU").createEntityManager();
     entityManager.getTransaction().begin();
               
               
     unregister();
     // refresh the viewer
              
     }
     }

     @Override
     public boolean equals(Object o) {
     throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
     }

     @Override
     public int hashCode() {
     throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
     }

     @Override
     public void paintIcon(Component c, Graphics g, int x, int y) {
     throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
     }

     @Override
     public int getIconWidth() {
     throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
     }

     @Override
     public int getIconHeight() {
     throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
     }
     */

    private class SearchPanel extends JPanel
    {

        /**
         *
         */
        private JComboBox tableListBox;
        /**
         *
         */
        private JComboBox dependentBox;
        /**
         *
         */
        private final JToggleButton displayButton;


        /**
         *
         */
        public SearchPanel()
        {
            /*
             *jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "CommonParameters", "LOVs", "Cookies" })); 
             */
            this.dependentBox = new JComboBox();
            //
            this.tableListBox = new JComboBox();
            this.tableListBox.addActionListener( new ActionListener()
            {
                @Override
                public void actionPerformed( ActionEvent evt )
                {
                    fillDependentBox( evt );
                }

            } );
            this.tableListBox.setModel( new DefaultComboBoxModel( new String[]
            {
                "CommonParameters" , "LOVs" , "Question Category"
            } ) );

            //
            this.displayButton = new JToggleButton( "Display" );
            this.displayButton.addActionListener( new ActionListener()
            {
                @Override
                public void actionPerformed( ActionEvent evt )
                {
                    display( evt );
                }

            } );

            //
            this.setLayout( new BorderLayout() );
            this.add( tableListBox , BorderLayout.LINE_START );
            this.add( dependentBox , BorderLayout.CENTER );
            this.add( displayButton , BorderLayout.LINE_END );
        }


        /**
         * @param evt
         */
        private void display( ActionEvent evt )
        {
            String selectedItem = (String) this.tableListBox.getSelectedItem();
            switch ( selectedItem )
            {
                case "CommonParameters":
                    displayCommonParameters();
                    break;
                case "LOVs":
                    displayGeneralLOV();
                    break;
                case "Question Category":
                    displayCategories();
                    break;
                default:
                    //   displayNoCookies();
                    System.out.println(
                            "hello from : " + this.tableListBox.getSelectedItem()
                            + " and " + this.dependentBox.getSelectedItem() );
            }
        }


        /**
         * @param evt
         */
        private void fillDependentBox( ActionEvent evt )
        {
            //
            if ( evt.getSource() instanceof JComboBox )
            {
                JComboBox jcb = (JComboBox) evt.getSource();
                System.out.println(
                        "hello from the event source : " + jcb.getSelectedItem() );
            }
            else
            {
                System.out.println(
                        "hello from the global var : " + this.tableListBox.getSelectedItem() );
            }

            this.dependentBox.removeAllItems();

            /*
             * Make a new list to populate the box and then for every element in
             * the list:
             */
            int numItems = (int) ( Math.random() * 10 );
            for ( int i = 0; i < numItems; i++ )
            {
                dependentBox.addItem( "Ref Period 200" + i );
            }

//            this.dependentBox.revalidate();
            this.dependentBox.repaint();
            this.dependentBox.updateUI();
        }

    }

}